package com.jf.yytgd.web;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.google.code.kaptcha.Constants;
import com.jf.yytgd.entity.bean.User;
import com.jf.yytgd.entity.dto.token.TokenDTO;
import com.jf.yytgd.entity.dto.user.UserBasicDTO;
import com.jf.yytgd.entity.dto.user.UserFullDTO;
import com.jf.yytgd.entity.dto.user.UserLoginDTO;
import com.jf.yytgd.entity.dto.user.UserRegisterDTO;
import com.jf.yytgd.service.TokenService;
import com.jf.yytgd.service.UserService;
import com.jf.yytgd.utils.FileUtil;
import com.jf.yytgd.utils.JwtUtil;
import com.jf.yytgd.utils.Msg;
import jakarta.annotation.Resource;
import jakarta.servlet.http.Cookie;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.validation.Errors;
import org.springframework.validation.FieldError;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.time.LocalTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created with IntelliJ IDEA
 * Description: 用户控制层
 * User:22954
 * Date:2025-01-13
 * Time:13:02
 */
@RequestMapping("/user")
@RestController
public class UserController {
    @Resource
    private UserService userService;
    @Resource
    private TokenService tokenService;

    @GetMapping("/checkU")
    public Msg checkUsername(@RequestParam("username") String username) {
        boolean exists = isUsernameExist(username);
        Msg msg = Msg.success();
        msg.addData("exists", exists);
        System.out.println(msg);
        return msg;
    }

    @GetMapping("/checkN")
    public Msg checkNickname(@RequestParam("nickname") String nickname) {
        boolean exists = isNicknameExist(nickname);
        Msg msg = Msg.success();
        msg.addData("exists", exists);
        return msg;
    }

    private boolean isNicknameExist(String nickname) {
        QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
        userQueryWrapper.eq("nickname", nickname);
        return userService.exists(userQueryWrapper);
    }

    private boolean isUsernameExist(String username) {
        QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
        userQueryWrapper.eq("username", username);
        return userService.exists(userQueryWrapper);
    }

    @PostMapping("/register")
    public Msg register(@RequestBody @Validated UserRegisterDTO user,
                        HttpSession session,
                        Errors errors) {
        // 检查数据验证是否有误
        List<FieldError> fieldErrors = errors.getFieldErrors();
        Msg msg;
        if (fieldErrors.isEmpty()) {
            // 检查昵称和用户名
            if (isUsernameExist(user.getUsername())) {
                msg = Msg.failed();
                msg.addData("username", "exist");
                return msg;
            }
            if (isNicknameExist(user.getNickname())) {
                msg = Msg.failed();
                msg.addData("nickname", "exist");
                return msg;
            }
            // 验证码
            if (!verifyCode(session, user.getVerificationCode())) {
                System.out.println(user.getVerificationCode());
                msg = Msg.failed();
                msg.addData("verificationCode", "wrong");
                return msg;
            }
            // 保存头像图片
            if (!savePortrait(user.getPortrait(), user)) {
                return Msg.failed(500, "portrait save failed");
            }
            userService.saveUser(user);
            return Msg.success();
        } else {
            Map<String, String> map = new HashMap<>();
            for (FieldError fieldError : fieldErrors) {
                map.put(fieldError.getField(), fieldError.getDefaultMessage());
            }
            msg = Msg.failed("data validation error");
            msg.addData(map);
            return msg;
        }
    }

    private boolean savePortrait(MultipartFile portrait, UserRegisterDTO user) {
        boolean flag = true;
        if (portrait != null) {
            String portraitPath = FileUtil.saveFile(portrait);
            if (portraitPath != null) {
                user.setPortraitPath(portraitPath);
            } else {
                flag = false;
            }
        } else {
            user.setPortraitPath(UserRegisterDTO.DEFAULT_PORTRAIT_PATH);
        }
        return flag;
    }

    private boolean verifyCode(HttpSession session, String verificationCode) {
        boolean verifiedSuccess = true;
        // 清除kaptcha缓存
        String kaptchaKey = (String) session.getAttribute(Constants.KAPTCHA_SESSION_KEY);
        session.removeAttribute(Constants.KAPTCHA_SESSION_KEY);
        LocalTime kaptchaTime = (LocalTime) session.getAttribute(Constants.KAPTCHA_SESSION_DATE);
        session.removeAttribute(Constants.KAPTCHA_SESSION_KEY);
        if (verificationCode != null && kaptchaTime != null) {
            // 检验过期
            LocalTime now = LocalTime.now();
            if (now.minusMinutes(3).isAfter(kaptchaTime)) {
                verifiedSuccess = false;
            } else {
                // 验证匹配
                if (!verificationCode.equals(kaptchaKey)) {
                    verifiedSuccess = false;
                }
            }
        } else {
            verifiedSuccess = false;
        }
        return verifiedSuccess;
    }

    @GetMapping("/login/info")
    public Msg info(@RequestParam("id") Integer id) {
        Msg msg;
        User user = userService.getById(id);
        if (user == null) {
            msg = Msg.failed("no such user");
        } else {
            UserFullDTO userDTO = new UserFullDTO();
            BeanUtils.copyProperties(user, userDTO);
            msg = Msg.success();
            msg.addData("user", userDTO);
        }
        return msg;
    }

    @GetMapping("/info")
    public Msg np(@RequestParam("id") Integer id) {
        User user = userService.getById(id);
        if (user == null) {
            return Msg.failed("no such user");
        } else {
            UserBasicDTO userDTO = new UserBasicDTO();
            BeanUtils.copyProperties(user, userDTO);
            Msg msg = Msg.success();
            msg.addData("user", userDTO);
            return msg;
        }
    }

    @PostMapping("/login")
    public Msg login(@RequestBody UserLoginDTO user,
                     HttpServletResponse response,
                     HttpSession session) {
        user.setPassword(DigestUtils.md5Hex(user.getPassword()));
        boolean login = userService.login(user);
        if (login) {
            // 添加cookie
            Cookie cookie = new Cookie("identifier", user.getIdentifier());
            cookie.setMaxAge(7 * 24 * 60 * 60);
            response.addCookie(cookie);
            // 添加session
            session.setAttribute("user", user.getId());
            return Msg.success();
        } else {
            return Msg.failed("no such user");
        }
    }
    @PostMapping("/login")
    public Msg login2(@RequestBody UserLoginDTO user,
                     HttpServletResponse response) {
        user.setPassword(DigestUtils.md5Hex(user.getPassword()));
        boolean login = userService.login(user);
        if (login) {
            String token = generateToken(user);
            tokenService.save(new TokenDTO(user.getId(), token));
            // 添加cookie
            Cookie cookie = new Cookie("token", token);
            cookie.setMaxAge(7 * 24 * 60 * 60);
            response.addCookie(cookie);
            return Msg.success().addData("token", token);
        } else {
            return Msg.failed("no such user");
        }
    }
    private String generateToken(UserLoginDTO user) {
        Map<String, String> payload = new HashMap<>();
        payload.put("userId", String.valueOf(user.getId()));
        return JwtUtil.generateToken(payload);
    }
}
